module dogre.rendersystemcapabilities;

import dogre.internals.utils;

enum
{
    CAPS_CATEGORY_COMMON,
    CAPS_CATEGORY_COMMON_2,
    CAPS_CATEGORY_D3D9,
    CAPS_CATEGORY_GL,
    CAPS_CATEGORY_COUNT
}
alias int CapabilitiesCategory;

immutable CAPS_CATEGORY_SIZE = 4;
immutable OGRE_CAPS_BITSHIFT = 32 - CAPS_CATEGORY_SIZE;
immutable CAPS_CATEGORY_MASK = ((1 << CAPS_CATEGORY_SIZE) - 1) << OGRE_CAPS_BITSHIFT;
static int OGRE_CAPS_VALUE(int cat, int val)
{
    return (cat << OGRE_CAPS_BITSHIFT) | (1 << val);
}

enum
{
    /// Supports generating mipmaps in hardware
    RSC_AUTOMIPMAP              = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 0),
    RSC_BLENDING                = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 1),
    /// Supports anisotropic texture filtering
    RSC_ANISOTROPY              = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 2),
    /// Supports fixed-function DOT3 texture blend
    RSC_DOT3                    = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 3),
    /// Supports cube mapping
    RSC_CUBEMAPPING             = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 4),
    /// Supports hardware stencil buffer
    RSC_HWSTENCIL               = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 5),
    /// Supports hardware vertex and index buffers
    RSC_VBO                     = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 7),
    /// Supports vertex programs (vertex shaders)
    RSC_VERTEX_PROGRAM          = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 9),
    /// Supports fragment programs (pixel shaders)
    RSC_FRAGMENT_PROGRAM        = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 10),
    /// Supports performing a scissor test to exclude areas of the screen
    RSC_SCISSOR_TEST            = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 11),
    /// Supports separate stencil updates for both front and back faces
    RSC_TWO_SIDED_STENCIL       = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 12),
    /// Supports wrapping the stencil value at the range extremeties
    RSC_STENCIL_WRAP            = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 13),
    /// Supports hardware occlusion queries
    RSC_HWOCCLUSION             = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 14),
    /// Supports user clipping planes
    RSC_USER_CLIP_PLANES        = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 15),
    /// Supports the VET_UBYTE4 vertex element type
    RSC_VERTEX_FORMAT_UBYTE4    = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 16),
    /// Supports infinite far plane projection
    RSC_INFINITE_FAR_PLANE      = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 17),
    /// Supports hardware render-to-texture (bigger than framebuffer)
    RSC_HWRENDER_TO_TEXTURE     = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 18),
    /// Supports float textures and render targets
    RSC_TEXTURE_FLOAT           = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 19),
    /// Supports non-power of two textures
    RSC_NON_POWER_OF_2_TEXTURES = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 20),
    /// Supports 3d (volume) textures
    RSC_TEXTURE_3D              = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 21),
    /// Supports basic point sprite rendering
    RSC_POINT_SPRITES           = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 22),
    /// Supports extra point parameters (minsize, maxsize, attenuation)
    RSC_POINT_EXTENDED_PARAMETERS = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 23),
    /// Supports vertex texture fetch
    RSC_VERTEX_TEXTURE_FETCH = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 24),
    /// Supports mipmap LOD biasing
    RSC_MIPMAP_LOD_BIAS = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 25),
    /// Supports hardware geometry programs
    RSC_GEOMETRY_PROGRAM = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 26),
    /// Supports rendering to vertex buffers
    RSC_HWRENDER_TO_VERTEX_BUFFER = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 27),

    /// Supports compressed textures
    RSC_TEXTURE_COMPRESSION = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 0),
    /// Supports compressed textures in the DXT/ST3C formats
    RSC_TEXTURE_COMPRESSION_DXT = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 1),
    /// Supports compressed textures in the VTC format
    RSC_TEXTURE_COMPRESSION_VTC = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 2),
    /// Supports compressed textures in the PVRTC format
    RSC_TEXTURE_COMPRESSION_PVRTC = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 3),
    /// Supports fixed-function pipeline
    RSC_FIXED_FUNCTION = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 4),
    /// Supports MRTs with different bit depths
    RSC_MRT_DIFFERENT_BIT_DEPTHS = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 5),
    /// Supports Alpha to Coverage (A2C)
    RSC_ALPHA_TO_COVERAGE = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 6),
    /// Supports Blending operations other than +
    RSC_ADVANCED_BLEND_OPERATIONS = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 7),

    // ***** DirectX specific caps *****
    /// Is DirectX feature "per stage constants" supported
    RSC_PERSTAGECONSTANT = OGRE_CAPS_VALUE(CAPS_CATEGORY_D3D9, 0),

    // ***** GL Specific Caps *****
    /// Supports openGL GLEW version 1.5
    RSC_GL1_5_NOVBO    = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 1),
    /// Support for Frame Buffer Objects (FBOs)
    RSC_FBO              = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 2),
    /// Support for Frame Buffer Objects ARB implementation (regular FBO is higher precedence)
    RSC_FBO_ARB          = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 3),
    /// Support for Frame Buffer Objects ATI implementation (ARB FBO is higher precedence)
    RSC_FBO_ATI          = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 4),
    /// Support for PBuffer
    RSC_PBUFFER          = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 5),
    /// Support for GL 1.5 but without HW occlusion workaround
    RSC_GL1_5_NOHWOCCLUSION = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 6),
    /// Support for point parameters ARB implementation
    RSC_POINT_EXTENDED_PARAMETERS_ARB = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 7),
    /// Support for point parameters EXT implementation
    RSC_POINT_EXTENDED_PARAMETERS_EXT = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 8),
}
alias int Capabilities;



extern(C)
{
    bool call_hasCapability(void* ptr, Capabilities cap);
}

class RenderSystemCapabilities
{
    mixin(Wrapper);

    bool hasCapability(Capabilities cap)
    {
        return call_hasCapability(p, cap);
    }
}